package pt.isel.pdm.ouryamba;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.view.MenuItem;

@SuppressLint("Registered")
public class BaseActivity extends Activity implements OnSharedPreferenceChangeListener
{
	protected General app;
	private AlertDialog alertDialog;
	
	
//Own methods
	
	/**
	 * Display an alert dialog on the screen saying the preferences need to be fill.
	 * First checks if the dialog is null and if so, creates the dialog with the help of 
	 * AlertDialog.Builder. If this method is called and the dialog was previously created, it
	 * only shows the dialog (because the message will not change).
	 * The reason for this code design is to don't waste resources (this case is mainly time)
	 * because the dialog can be created only once but shown multiple times.
	 * 
	 * Why final?
	 * Because there was no need for children activities override this method.
	 * This is declared here to avoid code replication over the children activities.
	 * 
	 * Why protected?
	 * To denote that visibility is only for children. For example, DetailActivity won't need this
	 * method.
	 */
	protected final void showLoginConfigAlertDialog()
	{
		if(alertDialog == null)
		{
			final class DummyListener implements DialogInterface.OnClickListener
			{
				@Override
				public void onClick(DialogInterface dialog, int which) 
				{
					switch(which)
					{
						case DialogInterface.BUTTON_POSITIVE:
							startActivity(new Intent(BaseActivity.this.getApplicationContext(), PreferencesActivity.class));
							break;
						case DialogInterface.BUTTON_NEGATIVE:
							finish();
							break;
					}
					dialog.dismiss();
				}
			};
			DummyListener dl = new DummyListener();
			AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
			alertDialogBuilder.setTitle(getResources().getString(R.string.configErrorDialgTitle));
			alertDialogBuilder.setMessage(getResources().getString(R.string.configErrorDialgMessage));
			alertDialogBuilder.setPositiveButton(getResources().getString(R.string.preferences), dl);
			alertDialogBuilder.setNegativeButton(getResources().getString(R.string.configErrorDialgNegButton), dl);
			alertDialog = alertDialogBuilder.create();
			alertDialog.setCancelable(false);
		}
		alertDialog.show();	
	}

	
//Activity methods
	
	/**
	 * Initialize the common variables for children activities.
	 * Initialize the {@code app} variable with a reference for General class.
	 * Also register the listener for the variable {@code prefs} that exists in {@code app}. This 
	 * affection is done here because this class is the one that will serve as listener for every
	 * change made in preferences.
	 * 
	 * @see #onSharedPreferenceChanged(SharedPreferences, String);
	 * */
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		app = (General) getApplication();
		app.prefs.registerOnSharedPreferenceChangeListener(this);
	}
		
	/**
	 * Check if the preferences are filled before showing any children activities.
	 * If the preferences are not filled, is shown an dialog with an alert message.
	 * 
	 * Call the method assertPreferences() that exist in General class to check if the preferences
	 * are filled and if don't, call the method showLoginConfigAlertDialog() that exist in this
	 * class, to show the alert dialog.
	 * 
	 * This is to prevent the user from doing actions in activities that need some preferences
	 * that actually don't exist.
	 * 
	 * @see General#assertPreferences()
	 * @see #showLoginConfigAlertDialog()
	 * */
	@Override
	public void onResume()
	{
		super.onResume();
		if(!app.assertPreferences())
		{
			showLoginConfigAlertDialog();
		}
	}
	
	/**
	 * Delegate the behavior for each menu item when it's clicked.
	 * 
	 * Why this is doing here?
	 * Because we have a shared menu, meaning all children activities will have access to all this
	 * options. However, each children activity may have some different menu items.
	 * Having this code here, allow the children activities to only specify their's specific items on 
	 * the menu, having these ones already specified because they are common to all activities.
	 * 
	 * When the item clicked is the preferences option, the action is to open the PreferencesActivity.
	 * */
    @Override
	public boolean onOptionsItemSelected(MenuItem item) 
    {
		switch(item.getItemId())
		{
			case R.id.action_preferences:
				startActivity(new Intent(this, PreferencesActivity.class));
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}	
	
    /**
     * Delegate the behavior when the activity is destroyed.
     * 
     * When it's destroyed we want to know if it is the last one to be shown before exit, so we can
     * stop the automatic update asynchronous task because it should not be running if the user want
     * to leave the application.
     * Since the two last activities the user can see ate the TimelineActivity and StatusActivity,
     * it checks whether this activity (can be one of the both referenced earlier) is the last
     * activity to be shown within the context of the application.
     * 
     * @see General#stopAutomaticUpdate()
     * */
    @Override
	protected void onDestroy() {
		if(isTaskRoot())
		{
			app.stopAutomaticUpdate();
		}
    	super.onDestroy();
	}
    
    
//OnSharedPreferenceChangeListener methods

	/**
     * Delegate the behavior when some preference is changed.
     * 
     * When the preference changed was the user name, password or API URL, the action will be reset
     * the {@code twitter} variable of the General class. It resets the variable (set it to null)
     * because it have to be created again with the new values that have being changed.
     * 
     * When the preference changed was the maximum number of characters allowed in the status
     * message, the action will be reset the variable {@code maxChars} of the General class. It 
     * resets the variable (set it to null) because this way indicates that the value should be
     * fetched again from the preferences.
     * 
     * When the preference changed was the maximum number of messages to show in the timeline, the
     * action will be reset the variable {@code maxMsgToShow} of the General class. It resets the 
     * variable (set it to null) because this way indicates that the value should be fetched again
     * from the preferences.
     * 
     * When the preference changed was the maximum number of messages to store in the timeline 
     * private list, the action will be reset the variable {@code maxMsgStored} of the General class.
     * It resets the variable (set it to null) because this way indicates that the value should be 
     * fetched again from the preferences.
     * 
     * When the preference changed was the interval of the automatic updates, the action will be 
     * reset the variable {@code automaticUpdateInterval} of the General class.
     * It resets the variable (set it to zero) because this way indicates that the value should be 
     * fetched again from the preferences.
     * 
     * When the preference changed was the switch that enables/disables the automatic updates of the
     * timeline private list of statuses, the action will depend on the new value. If the new value
     * of the preference is to enable the automatic update, we enable the automatic updated. This is
     * enough to start the process because it uses the variable {@code automaticUpdateInterval} which
     * indicates what we described earlier and also indicates whether or not the automatic updates are
     * enabled or not.
     * If the preference is set to disable, we will disable the automatic updates (stop the process)
     * and we call the {@code resetAutomaticUpdate} method to indicate the automatic updates are 
     * disabled.
     * 
     * @see General#resetTwitter()
     * @see General#resetMaxChars()
     * @see General#resetMaxMsgToShow()
     * @see General#resetMaxMsgStored()
     * @see General#resetAutomaticUpdateInterval()
     * @see General#startAutomaticUpdate()
     * @see General#stopAutomaticUpdate()
     * @see General#resetAutomaticUpdate()
     * */
	@Override
	public void onSharedPreferenceChanged(SharedPreferences prefs, String key)
	{
		if(key.equals(app.PASSWORD_PREF_KEY) || key.equals(app.USER_PREF_KEY) || key.equals(app.URL_PREF_KEY))
		{
			app.resetTwitter();
		}
		else if(key.equals(app.STATUS_LENGTH_PREF_KEY))
		{
			app.resetMaxChars();
		}
		else if(key.equals(app.MSG_NUMBER_TO_SHOW_PREF_KEY))
		{
			app.resetMaxMsgToShow();
		}
		else if(key.equals(app.MSG_NUMBER_TO_STORE_PREF_KEY))
		{
			app.resetMaxMsgStored();
			app.resetTwitter();
		}
		else if(key.equals(app.AUTOMATIC_UPDATE_PERIOD_PREF_KEY))
		{
			app.resetAutomaticUpdateInterval();
		}
		else if(key.equals(app.AUTOMATIC_UPDATE_PREF_KEY))
		{
			boolean cbPref = prefs.getBoolean(key, false);
			if(cbPref)
			{
				app.startAutomaticUpdate();
			}
			else
			{
				app.stopAutomaticUpdate();
				app.resetAutomaticUpdate();
			}
		}
	}

}
